#region Imports
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Context;
using InsightAnimals = PHSRAG.Insight21.Humans;
#endregion

namespace PHSRAG.Insight21.InsightWebControls
{
    /// <summary>
    /// Summary description for AnimalsSubModuleNavigation.
    /// </summary>
    [ToolboxData("<{0}:AnimalsSubModuleNavigation runat=server />")]
    [Designer(typeof(AnimalsSubModuleNavigationDesigner), typeof(IDesigner))]
    public class AnimalsSubModuleNavigation : SubNavigation
    {
        #region Constants
        private const string selectedAnimalsSubModuleNavigationLinkKey =
            "SelectedAnimalsSubModuleNavigationLink_DB495D98-6B92-473c-B545-CBBDF6E7E9DF";

        private const string NavigateCommand = "Navigate to new page";
        #endregion

        #region Instance Variables
        private LinkButton formsLinkButton;
        private LinkButton protocolDetailsLinkButton;
        private LinkButton staffAndAccessLinkButton;
        private LinkButton attachmentsLinkButton;
        private LinkButton workflowLinkButton;
        private LinkButton submissionLinkButton;
        #endregion

        #region instance variales(private)
        private bool showForm = true;
        private bool showProtocolDetail = true;
        private bool showStaffAndAccess = true;
        private bool showAttachment = true;
        private bool showSubmission = true;
        private bool showWorkFlow = true;
        private string overAllStatus = string.Empty;
        private bool isLocked;
        private bool isProcessAvailable;
        private int submitterId;
        private InsightAnimals.ProtocolProcess process;
        #endregion

        #region Behavior Control properties
        /// <summary>
        /// Defines which button links are displayed
        /// </summary>
        /// <summary>Shows or hides the form link from the navigation control</summary>

        /// <summary>
        /// Sets the overall status and type of the process
        /// </summary>
        public InsightAnimals.ProtocolProcess ProtocolProcess
        {
            get { return process; }
            set
            {
                if (value != null)
                {
                    process = (InsightAnimals.ProtocolProcess)value;
                    overAllStatus = process.Status;
                    isProcessAvailable = true;
                    isLocked = process.Locked;
                    submitterId = process.SubmitterId;
                }
            }
        }
        /// <summary>Sets the overall status and Lock status of the protocol.</summary>
        public InsightAnimals.Protocol Protocol
        {
            set
            {
                if (value != null)
                {
                    if (String.IsNullOrEmpty(overAllStatus))
                    {
                        overAllStatus = ((InsightAnimals.Protocol)value).OverallStatus;
                        isLocked = ((InsightAnimals.Protocol)value).IsLocked;
                    }
                }
            }
        }

        /// <summary>
        /// Set the selected link so that on load, the appropriate tab may be shown highlighted. This property is invoked
        /// by pages while vectoring to other pages which host this navigation control.
        /// </summary>
        public string SelectedLink
        {
            set { Page.Session[SelectedSubNavigationLinkKey] = value; }
        }

        #endregion


        #region Implementations for abstract properties and methods from Base Class SubNavigation

        /// <summary>
        /// Create all controls in the AnimalsSubNavigation.
        /// </summary>
        protected override void CreateControls()
        {
            SetRequiredControls();
            Controls.Clear();

            if (showProtocolDetail)
            {
                protocolDetailsLinkButton = new LinkButton();
                protocolDetailsLinkButton.CommandName = protocolDetailsLinkButton.Text = "Protocol Details";
                protocolDetailsLinkButton.CommandArgument =
                Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.ProtocolDetailsURL", "");
                protocolDetailsLinkButton.CausesValidation = false;
            }
            if (showForm)
            {
                formsLinkButton = new LinkButton();
                formsLinkButton.CommandName = formsLinkButton.Text = "Forms";
                formsLinkButton.CommandArgument =
                Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.ProtocolProcessOverviewURL", "");
                formsLinkButton.CausesValidation = false;
            }
            if (showStaffAndAccess)
            {
                staffAndAccessLinkButton = new LinkButton();
                staffAndAccessLinkButton.CommandName = staffAndAccessLinkButton.Text = "Staff & Access";
                staffAndAccessLinkButton.CommandArgument =
                    Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.StaffAndAccessURL", "");
                staffAndAccessLinkButton.CausesValidation = false;
            }
            if (showAttachment)
            {
                attachmentsLinkButton = new LinkButton();
                attachmentsLinkButton.CommandName = attachmentsLinkButton.Text = "Attachments";
                attachmentsLinkButton.CommandArgument =
                        Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.AttachmentsURL", "");
                attachmentsLinkButton.CausesValidation = false;
            }

            if (showSubmission)
            {
                submissionLinkButton = new LinkButton();
                submissionLinkButton.CommandName = submissionLinkButton.Text = "Submission";
                submissionLinkButton.CommandArgument =
                    Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.SubmissionURL", "");
                submissionLinkButton.CausesValidation = false;
            }
            if (showWorkFlow)
            {
                workflowLinkButton = new LinkButton();
                workflowLinkButton.CommandName = workflowLinkButton.Text = "Workflow";
                workflowLinkButton.CommandArgument =
                    Utility.Settings.GetKeyValue("SubModuleNavigation.Humans.WorkflowURL", "");
                workflowLinkButton.CausesValidation = false;
            }
        }
        /// <summary>
        /// Sets the required controls(links)which needs to be available depending on the status and lockstatus of the protocol.
        /// Note:User access level(rights) is not yet defined.
        /// Also: for an amendment, sets which tabs are visible based on 
        /// </summary>
        private void SetRequiredControls()
        {
            switch (overAllStatus)
            {
                case InsightAnimals.Constants.ProtocolProcessStatus.WorkInProgress:
                case InsightAnimals.Constants.ProtocolOverallStatusText.WorkInProgress:
                    showProtocolDetail = false;
                    showWorkFlow = false;
                    SetSubmissionTabFlag();
                    break;

                case InsightAnimals.Constants.ProtocolProcessStatus.Pending:
                case InsightAnimals.Constants.ProtocolOverallStatusText.Pending:
                case InsightAnimals.Constants.ProtocolProcessStatus.Submitted:
                case InsightAnimals.Constants.ProtocolOverallStatusText.Submitted:
                case InsightAnimals.Constants.ProtocolOverallStatusText.Hold:
                case InsightAnimals.Constants.ProtocolOverallStatusText.HoldLapsed:
                    if (isLocked)
                    {
                        showForm = false;
                        showSubmission = false;
                    }
                    else
                    {
                        if (!isProcessAvailable)
                        {
                            showForm = false;
                        }
                    }
                    if (showSubmission)
                    {
                        SetSubmissionTabFlag();
                    }
                    break;

                default:
                    showForm = false;
                    showSubmission = false;
                    showWorkFlow = false;
                    break;
            }
            if (isProcessAvailable)
            {
                showAttachment = true;
                showStaffAndAccess = (process.Type == PHSRAG.Insight21.Humans.Constants.AnimalProtocolProcessType.InitialReview);

                if (process.Type == PHSRAG.Insight21.Humans.Constants.AnimalProtocolProcessType.Amendment
                    || process.Type == PHSRAG.Insight21.Humans.Constants.AnimalProtocolProcessType.TriennialReview)
                {
                    showAttachment = process.ShowAttachments;
                    showStaffAndAccess = process.ShowStaff;
                }
            }
            else
            {
                showWorkFlow = false;
            }
        }

        /// <summary>
        /// Determines if the Submission tab should be displayed
        /// based on whether the logged in user has Edit or Manage
        /// permission to the protocol
        /// </summary>
        private void SetSubmissionTabFlag()
        {
            //put a try catch block in order not to catch an error if a user is not an Insight user.
            try
            {
                Policy.ICachePolicy cachePolicy =
                  (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];
                UserContext userContext = (UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey);

                // If the user is the process submitter (creator) show the submission tab
                showSubmission = userContext.DomainUserId == submitterId;
                if (showSubmission) return;

                // Otherwise they need direct edit access
                foreach (InsightAnimals.BaseStudyPerson person in ProtocolProcess.GetUsersWithMinimumPermission(ProtocolProcess.Protocol.EditPermission))
                {
                    if (person.UserId == userContext.DomainUserId)
                    {
                        showSubmission = true;
                        break;
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// The selected link cell is given a prefix and suffix image as adornments. In addition the background of the
        /// cell is of a different style.
        /// </summary>
        private void CreateSelectedLinkAdornments(TableRow row)
        {
            LinkButton selectedLink = GetSelectedLink();
            if (selectedLink != null)
            {
                foreach (TableCell cell in row.Cells)
                {
                    if ((cell.Controls.Count == 1) && (cell.Controls[0] == selectedLink))
                    {
                        cell.CssClass = "SubModuleNavigationSelectedSummary";

                        TableCell adornmentCell = new TableCell();
                        adornmentCell.CssClass = "SubModuleNavigationSelectedSummaryAdornment";
                        row.Cells.AddAt(row.Cells.GetCellIndex(cell), adornmentCell);

                        const string prefixImage = "../Images/Row2_Left.gif";
                        System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(Context.Server.MapPath(prefixImage));
                        Image image = new Image();
                        image.ImageUrl = prefixImage;
                        adornmentCell.Width = bitmap.Width;
                        adornmentCell.Controls.Add(image);

                        adornmentCell = new TableCell();
                        adornmentCell.CssClass = "SubModuleNavigationSelectedSummaryAdornment";
                        row.Cells.AddAt(row.Cells.GetCellIndex(cell) + 1, adornmentCell);

                        const string suffixImage = "../Images/Row2_Right.gif";
                        bitmap = new System.Drawing.Bitmap(Context.Server.MapPath(suffixImage));
                        image = new System.Web.UI.WebControls.Image();
                        image.ImageUrl = suffixImage;
                        adornmentCell.Width = bitmap.Width;
                        adornmentCell.Controls.Add(image);

                        break;
                    }
                }
            }
        }

        /// <summary>
        /// Setup the control tree to reflect the actual (and exact) layout of the controls 
        /// within the AnimalsSubNavigation.
        /// </summary>
        protected override void GenerateControlTree()
        {
            Table table = new Table();
            Controls.Add(table);
            table.CssClass = "SubModuleSummaryNavigation";
            table.EnableViewState = false;

            TableRow row = new TableRow();
            table.Rows.Add(row);

            TableCell cell = new TableCell();
            row.Cells.Add(cell);
            cell.CssClass = "SubModuleSummaryNavigationFillerCell";
            cell.Controls.Add(new LiteralControl("&nbsp;"));

            cell = new TableCell();
            row.Cells.Add(cell);

            table = new Table();
            cell.Controls.Add(table);

            row = new TableRow();
            table.Rows.Add(row);

            cell = new TableCell();
            row.Cells.Add(cell);

            if (showProtocolDetail)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(protocolDetailsLinkButton);
            }
            if (showForm)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(formsLinkButton);
            }
            if (showStaffAndAccess)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(staffAndAccessLinkButton);
            }
            if (showAttachment)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(attachmentsLinkButton);
            }
            if (showSubmission)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(submissionLinkButton);
            }
            if (showWorkFlow)
            {
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(workflowLinkButton);
            }
            CreateSelectedLinkAdornments(row);
        }

        /// <summary>
        /// Retrieve the name of the link that was last clicked on.
        /// </summary>
        /// <returns>Reference to the link button corresponding to the clicked link</returns>
        protected override LinkButton GetSelectedLink()
        {
            // Anytime a link is clicked on, the OnBubbleEvent handler stores the name of the link 
            // in the session. Retrieve that name and return the corresponding link button reference.

            object o = Page.Session[SelectedSubNavigationLinkKey];
            if (o != null)
            {
                string commandName = (string)o;


                if (null != protocolDetailsLinkButton)
                {
                    if (commandName == protocolDetailsLinkButton.CommandName)
                        return protocolDetailsLinkButton;
                }
                if (null != formsLinkButton)
                {
                    if (commandName == formsLinkButton.CommandName)
                        return formsLinkButton;
                }

                if (null != staffAndAccessLinkButton)
                {
                    if (commandName == staffAndAccessLinkButton.CommandName)
                        return staffAndAccessLinkButton;
                }

                if (null != attachmentsLinkButton)
                {
                    if (commandName == attachmentsLinkButton.CommandName)
                        return attachmentsLinkButton;
                }

                if (null != workflowLinkButton)
                {
                    if (commandName == workflowLinkButton.CommandName)
                        return workflowLinkButton;
                }

                if (null != submissionLinkButton)
                {
                    if (commandName == submissionLinkButton.CommandName)
                        return submissionLinkButton;
                }
            }
            if (protocolDetailsLinkButton == null)
            {
                return formsLinkButton;
            }
            else
            {
                return protocolDetailsLinkButton;
            }
        }

        /// <summary>
        /// Delegate used by page to be informed of navigation event
        /// </summary>
        public delegate void NavigateEventHandler();

        /// <summary>
        /// Calls on base to initialize the instance
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }

        /// <summary>
        /// Notifies NavigateEventHandlers if navigation is occurring, and makes a call
        /// to the base method
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        protected override bool OnBubbleEvent(object source, EventArgs args)
        {
            if ((args is CommandEventArgs) && (source is LinkButton))
            {
                NavigateEventHandler handler = (NavigateEventHandler)Events[NavigateCommand];
                try
                {
                    // if the page doesn't want to redirect, it can throw an exception to prevent redirection
                    if (handler != null)
                        handler();
                    return base.OnBubbleEvent(source, args);
                }
                catch
                {
                    return true;
                }
            }
            return base.OnBubbleEvent(source, args);
        }

        /// <summary>
        /// Gets the key used to the store the SelectedSubNavigationLink information
        /// in any hash table. 
        /// </summary>
        protected override string SelectedSubNavigationLinkKey
        {
            get
            {
                return selectedAnimalsSubModuleNavigationLinkKey;
            }
        }

        #endregion


        #region Event Handlers
        /// <summary>
        /// Disable view state.
        /// </summary>
        /// <param name="e">Argument associated with the load event.</param>
        protected override void OnLoad(EventArgs e)
        {
            EnableViewState = false;
            base.OnLoad(e);
        }
        #endregion
    }
    #region Class AnimalsSubModuleNavigationDesigner
    /// <summary>
    /// Designer associated with the control.
    /// </summary>
    public class AnimalsSubModuleNavigationDesigner : ControlDesigner
    {
        #region Overrides
        /// <summary>
        /// Force the control to create its child controls for display at design time.
        /// </summary>
        /// <returns>HTML representation of the control</returns>
        public override string GetDesignTimeHtml()
        {
            ((AnimalsSubModuleNavigation)Component).Design();
            return base.GetDesignTimeHtml();
        }
        #endregion
    }
    #endregion
}
